// Copyright (c) Huawei Technologies Co., Ltd. 2022-2022. All rights reserved.

// 用户管理
package user

import (
	"fleetmanager/api/common/query"
	"fleetmanager/api/model/user"
	"fleetmanager/api/service/constants"
	"fleetmanager/db/dao"
	redisPkg "fleetmanager/db/redis"
	"fleetmanager/logger"
	"fmt"
	"github.com/beego/beego/v2/server/web/context"
	"github.com/go-redis/redis"
	"github.com/pkg/errors"
)

// UserSecurityInfo
// @Description:
type UserSecurityInfo struct {
	AK    string
	SK    string
	Token string
}

type UserService struct {
	ctx    *context.Context
	logger *logger.FMLogger
}

func NewUserService(ctx *context.Context, logger *logger.FMLogger) *UserService {
	s := &UserService{
		ctx:    ctx,
		logger: logger,
	}
	return s
}

func (s *UserService) ListResConf() (*user.ReturnResConf, error) {
	offset, limit, err := s.queryCheck()
	if err != nil {
		return nil, err
	}
	count, total, resConfListFromDB, err := dao.GetUserResConf().List(limit, offset)
	if err != nil {
		s.logger.Error("list total resConf error:%+v", err)
		return nil, err
	}
	resConfRespList := user.ReturnResConf{}
	for _, resConf := range resConfListFromDB {
		resConfResp := getResConfigHandler(&resConf)
		resConfRespList.ResConfList = append(resConfRespList.ResConfList, resConfResp)
	}
	resConfRespList.Total = total
	resConfRespList.Count = count
	return &resConfRespList, nil
}

func (s *UserService) AdminListAllUser() (*user.ListUserResp, error) {
	offset, limit, err := s.queryCheck()
	if err != nil {
		s.logger.Error("get offset and limit error:%+v", err)
		return nil, err
	}
	count, total, usersDB, err := dao.GetUser().List(limit, offset)
	if err != nil {
		s.logger.Error("Get all user err:%+v", err.Error())
		return nil, err
	}
	ListResp := user.ListUserResp{
		Total: total,
		Count: count,
	}
	for _, oneUser := range usersDB {
		userResp := getUserHandler(&oneUser)
		ListResp.Users = append(ListResp.Users, userResp)
	}
	return &ListResp, nil
}

func (s *UserService) GetResourceConfig(authUserId, queryId string, tLogger *logger.FMLogger) (*user.ReturnResConf, error) {
	// 认证身份的用户
	authUser, err := dao.GetUser().Get(dao.Filters{"id": authUserId})
	if err != nil {
		tLogger.Error("Get User info err:%+v", err.Error())
		return nil, err
	}

	// 管理员身份才能查询所有租户的信息
	if authUser.UserType != user.Administrator {
		if authUserId != queryId {
			tLogger.Error("userid not match the id in params")
			return nil, fmt.Errorf("auth user id %s not match query user id %s", authUserId, queryId)
		}
	}
	offset, limit, err := s.queryCheck()
	if err != nil {
		s.logger.Error("get offset and limit error:%+v", err)
		return nil, err
	}
	// 需要查询的用户租户
	count, total, userConfList, err := dao.GetUserResConf().ListByUserId(queryId, limit, offset)
	if err != nil {
		return nil, err
	}
	var resConfList []user.UserResourceConfig
	// 循环访问user信息
	for _, userConfDB := range userConfList {
		resConfResp := getResConfigHandler(&userConfDB)
		resConfList = append(resConfList, resConfResp)
	}
	ReturnResConfList := user.ReturnResConf{
		Total:       total,
		Count:       count,
		ResConfList: resConfList,
	}
	return &ReturnResConfList, nil
}

func (s *UserService) LogOut() error {
	RedisClient := redisPkg.GetRedisClient()
	defer redisPkg.CloseRedisClient(RedisClient)
	token := s.ctx.Input.Header("Auth-token")
	_, err := RedisClient.Del(token).Result()
	if err != nil {
		if errors.Is(err, redis.Nil) {
			return nil
		} else {
			return err
		}
	}
	return nil
}

func (s *UserService) queryCheck() (int, int, error) {
	offset, err := query.CheckOffset(s.ctx)
	if err != nil {
		return 0, 0, err
	}
	limit, err := query.CheckLimit(s.ctx)
	if err != nil {
		return 0, 0, err
	}

	return offset, limit, nil
}
func getResConfigHandler(userConf *dao.UserResConf) user.UserResourceConfig {
	resConf := user.UserResourceConfig{}
	resConf.OriProjectId = userConf.OriProjectId
	resConf.UserId = userConf.Userid
	resConf.Username = userConf.Username
	resConf.ProjectId = userConf.ProjectId
	resConf.Region = userConf.Region
	resConf.KeypairName = userConf.KeyPairName
	resConf.AccessKey = userConf.AccessKey
	resConf.SecretAccessKey = userConf.SecretAccessKey
	resConf.DomainName = userConf.DomainName
	resConf.AgencyName = userConf.AgencyName
	resConf.BuildScriptPath = userConf.BuildScriptPath
	resConf.AuxProxyPath = userConf.AuxProxyPath
	resConf.FileStorageRegion = userConf.FileStorageRegion
	resConf.DockerBuildScriptPath = userConf.DockerBuildScriptPath
	resConf.Id = userConf.Id
	resConf.Username = userConf.Username
	resConf.UserId = userConf.Id
	return resConf
}

func getUserHandler(userinfo *dao.User) user.QueryUserResp {
	userResp := user.QueryUserResp{
		Id:             userinfo.Id,
		UserName:       userinfo.UserName,
		Email:          userinfo.Email,
		Phone:          userinfo.Phone,
		LastLogin:      userinfo.LastLogin.Format(constants.TimeFormatLayout),
		UserType:       int(userinfo.UserType),
		Activation:     int(userinfo.Activation),
		TotalResNumber: userinfo.TotalResNumber,
	}
	return userResp
}
